package com.hll.spring_book.controller;

import com.hll.spring_book.annotion.loginAnno;
import com.hll.spring_book.pojo.User;
import com.hll.spring_book.service.user.UserService;
import com.hll.spring_book.util.CommonResult;
import com.hll.spring_book.util.Constants;
import com.hll.spring_book.util.SessionHelper;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.util.Calendar;
import java.util.List;
import java.util.UUID;

/**
 * @author: Mr.Hu
 * @create: 2021-03-30 09:18
 */
@RequestMapping("/user")
@RestController
public class UserController {
  private static File uploadFolder;

  static {
    /*原来是存到了 D:/upload下，唉, 应该jar包在哪个盘运行，就保存在哪把*/
    /*不能写成classLoader,否则打包jar的时候文件路径出错*/
    uploadFolder = new File(new ClassPathResource("").getPath(), "upload");
    if (!uploadFolder.exists()) {
      uploadFolder.mkdirs();
    }
  }

  @Resource private UserService userService;

  // 登入
  @loginAnno
  @PostMapping("login")
  public CommonResult login(@RequestBody User user, HttpServletRequest request) {
    user.setPassWord(DigestUtils.sha256Hex(user.getPassWord())); // sha256转化
    User rs = userService.login(user.getName(), user.getPassWord()); // 登录
    if (rs == null) return new CommonResult(Constants.FAIL, "用户名或密码错误", null);
    String token = String.valueOf(rs.hashCode()); // 设置session
    request.getSession().setAttribute(Constants.TOKEN, token);
    request.getSession().setAttribute(Constants.USER, rs); // 方便后面借阅
    return new CommonResult(Constants.SUCCESS, "登录成功", token); // token保存在浏览器的storage
  }

  @PostMapping("updateUserInfo")
  public CommonResult update(@RequestBody User user) {
    user = userService.update(user);
    if (user != null) return new CommonResult(Constants.SUCCESS, "修改成功", user);
    else return new CommonResult(Constants.FAIL, "修改失败", null);
  }

  // 注册
  @loginAnno
  @PostMapping("register")
  public CommonResult register(@RequestBody User user) {
    user.setPassWord(DigestUtils.sha256Hex(user.getPassWord()));
    User rs = userService.insert(user);
    if (rs == null) return new CommonResult(Constants.FAIL, "注册失败", null);
    return new CommonResult(Constants.SUCCESS, "注册成功", rs.hashCode());
  }

  @PostMapping("getInfo")
  public CommonResult getInfo() {
    User user = SessionHelper.getUser();
    return new CommonResult(Constants.SUCCESS, "成功", user);
  }

  @PostMapping("/uploadAvatar")
  public CommonResult uploadAvatar(@RequestParam(value = "file") MultipartFile file) {
    User user = SessionHelper.getUser();
    if (!file.isEmpty()
        && user != null
        && file.getContentType().contains("image")
        && file.getSize() < 1024 * 1024) {
      // target/class/upload/
      try {
        String uuid = UUID.randomUUID().toString();
        String time = String.valueOf(Calendar.getInstance().getTime().getTime());
        String fileName =
            time
                + uuid
                + "."
                + file.getContentType().substring(file.getContentType().lastIndexOf("/") + 1);

        File headPath = new File(uploadFolder.getAbsolutePath() + "/" + fileName);
        file.transferTo(headPath);

        /*删除旧照片*/
        if (user.getAvatar() != null && user.getAvatar().length() > 0) {
          File file1 = new File(uploadFolder.getAbsolutePath() + "/" + user.getAvatar());
          file1.delete();
        }
        // 保存文件名在数据库中
        user.setAvatar(fileName);
        user = userService.update(user);
        if (user.getAvatar() != null && user.getAvatar().length() > 0)
          return new CommonResult(Constants.SUCCESS, "success", fileName);
        else headPath.delete(); // 数据库失败，文件删除
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    return new CommonResult(Constants.FAIL, "error", null);
  }

  @loginAnno
  @ApiOperation(value = "返回指定地址的文件流")
  @ApiImplicitParams({
    @ApiImplicitParam(
        name = "url",
        value = "图片地址",
        required = true,
        paramType = "query",
        defaultValue = "default.jpg"),
  })
  @GetMapping("getAvatar")
  public void getUrlFile(@RequestParam(value = "url") String url, HttpServletResponse response) {
    /*获取不了session的attribute，只能获取session，tmd，去个锤子*/
    File file = new File(uploadFolder.getAbsolutePath() + "/" + url);

    // 判断文件是否存在如果不存在就返回默认图标
    if (!(file.exists() && file.canRead())) {
      file = new File(uploadFolder.getAbsolutePath() + "/" + "default.jpg");
    }
    if (!file.exists() && !file.canRead()) return; // 有问题了
    ServletOutputStream out = null;
    FileInputStream in = null;
    try {
      in = new FileInputStream(file);
      String[] dir = file.getPath().split("/");
      String fileName = dir[dir.length - 1];
      String[] array = fileName.split("[.]");
      String fileType = array[array.length - 1].toLowerCase();
      // 设置文件ContentType类型
      if ("jpg,jepg,gif,png".contains(fileType)) { // 图片类型
        response.setContentType("image/" + fileType);
      } else if ("pdf".contains(fileType)) { // pdf类型
        response.setContentType("application/pdf");
      } else { // 自动判断下载文件类型
        response.setContentType("multipart/form-data");
      }
      out = response.getOutputStream();
      // 读取文件流
      int len = 0;
      byte[] buffer = new byte[1024 * 10];
      while ((len = in.read(buffer)) != -1) {
        out.write(buffer, 0, len);
      }
      out.flush();
    } catch (Exception ignored) {
      ignored.printStackTrace();
    } finally {
      try {
        out.close();
        in.close();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

  @PostMapping("queryUsers")
  public List<User> queryUsers() {
    return userService.queryUsers(null);
  }
}
